package com.common.demo.filter;


import cn.hutool.core.text.AntPathMatcher;

import com.common.demo.service.loginservice;
import com.common.demo.util.JwtUtil;
import com.common.demo.util.UserContextHolder;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//import com.example.demo.demos.web.service.IUserService;

/**
 * JWT认证过滤器
 * @Description JwtAuthenticationFilter
 * @Author xiao xun
 * @Date 2025-08-27
 */
//@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    //private UserDetailsService userDetailsService;
    private loginservice service;


    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {


        // 从HTTP请求中提取JWT Token
        String jwtToken = getJwtFromRequest(request);

        // 如果JWT Token不为空且验证通过
        if (jwtToken != null && validateToken(jwtToken)) {
            try {
                // 使用JwtUtil工具类解析JWT Token，获取其中的声明信息
                // "陌"是JWT的签名密钥
                Claims claims = jwtUtil.parseJWT("陌", jwtToken);
                // 从声明中获取主题(subject)，即用户名
                String username = (String) claims.get("username");

                // 如果用户名存在且当前安全上下文中没有认证信息    && SecurityContextHolder.getContext().getAuthentication() == null
                if (username != null ) {

                    // 使用springsecurity提供的UserDetailsService接口
                    UserDetails userDetails = service.loadUserByUsername(username);
                    // 如果用户存在
                    if (userDetails != null) {
                        // 创建MemberDetails对象，封装用户详细信息用于Spring Security认证
                        //UserDetails userDetails = new MemberDetails(user);

                        //创建UsernamePasswordAuthenticationToken认证对象 参数分别为：用户详情、凭证（这里为null，因为使用JWT不需要凭证）、用户权限列表
                        UsernamePasswordAuthenticationToken authentication =
                                new UsernamePasswordAuthenticationToken(
                                        userDetails, null, userDetails.getAuthorities());
                        // 设置认证详情，包括请求的会话信息等
                        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                        // 将认证信息设置到Spring Security的上下文中

                        SecurityContextHolder.getContext().setAuthentication(authentication);


                    }
                }
            } catch (Exception e) {
                // 如果JWT解析或认证过程中出现异常，记录错误日志
                logger.error("JWT认证失败", e);
            }
        }

        // 继续执行过滤器链中的下一个过滤器
        filterChain.doFilter(request, response);

    }

    /**
     * 从请求中获取JWT Token
     * @param request HTTP请求
     * @return JWT Token
     */
    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        /*if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }*/
        return bearerToken;
    }
    
    /**
     * 验证JWT Token的有效性
     * @param token JWT Token
     * @return 是否有效
     */
    private boolean validateToken(String token) {
        // 在实际项目中，这里应该实现JWT的验证逻辑
        // 包括检查签名、过期时间等
        // 这里只是一个示例，直接返回true
        return token != null && !token.isEmpty();
    }
    

}